using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using ProjectEuler.Core.Helpers;

namespace ProjectEuler.Core
{
    public class Problem43 : IProjectEulerProblem
    {
        protected IEnumerable<string> GetAll0to9Pandigitals()
        {
            var permutationGenerator = new StringPerm("0123456789".Select(c => c.ToString()));
            var permuations = permutationGenerator.GetAllPermuations();
            return from permuation in permuations
                   where permuation.First() != '0'
                   select permuation;
        }

        protected IEnumerable<long> GetAll0to9PandigitalsWithUnusualProperty()
        {
            return from pandigital in GetAll0to9Pandigitals()
                   where HasUnusualProperty(pandigital)
                   select long.Parse(pandigital);
        }

        protected static bool HasUnusualProperty(string p)
        {
            return ThreeDigitSumDivisibleBy(p.Substring(1, 3), 2) &&
                   ThreeDigitSumDivisibleBy(p.Substring(2, 3), 3) &&
                   ThreeDigitSumDivisibleBy(p.Substring(3, 3), 5) &&
                   ThreeDigitSumDivisibleBy(p.Substring(4, 3), 7) &&
                   ThreeDigitSumDivisibleBy(p.Substring(5, 3), 11) &&
                   ThreeDigitSumDivisibleBy(p.Substring(6, 3), 13) &&
                   ThreeDigitSumDivisibleBy(p.Substring(7, 3), 17);
        }

        protected static bool ThreeDigitSumDivisibleBy(string threeDigits, int i)
        {
            return int.Parse(threeDigits) %i == 0;
        }

        public int Number
        {
            get { return 43; }
        }

        public string Description
        {
            get { return "Find the sum of all 0 to 9 pandigital numbers with the unusual divisibility property"; }
        }

        public string Answer
        {
            get { return GetAll0to9PandigitalsWithUnusualProperty().Sum().ToString(); }
        }
    }

    [TestFixture]
    public class Problem43Tests : Problem43
    {
        [Test]
        public void Can_test_3_digit_sum()
        {
            Assert.AreEqual(true, ThreeDigitSumDivisibleBy("406",2));
        }

        [Test]
        public void Can_test_for_unusual_property()
        {
            Assert.AreEqual(true, HasUnusualProperty("1406357289"));
        }

        [Test]
        public void Can_get_all_pandigitals_permutations()
        {
            var permutationGenerator = new StringPerm(new string[] {"0","1","2"});
            var permutations = permutationGenerator.GetAllPermuations().ToList();
            Assert.AreEqual(6,permutations.Count);
        }
    }
}